home *** CD-ROM | disk | FTP | other *** search
- /*
- * ttcptest.c
- *
- * Small example for a T/TCP-compliant client.
- *
- * This client tries to connect to the auth (identd) port of the
- * specified host using T/TCP. If T/TCP is not supported it falls
- * back to TCP.
- *
- * (C) Copyright 1996,1997 by Nordic Global Inc. All rights reserved.
- * T/TCP code for use with Miami only.
- *
- * 07/30/97
- */
-
- #include <proto/exec.h>
- #include <proto/miami.h>
- #include <proto/socket.h>
-
- #include <sys/socket.h>
- #include <netinet/tcp.h>
- #include <netdb.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
-
-
- struct Library *MiamiBase=0;
-
- static int dottcp=0;
-
- #define REQUEST "1 : 1\r\n"
-
- void get_response(int sockfd,char *buf,int max) {
- int len=0,le;
- while(len<max-1) {
- le=recv(sockfd,buf+len,max-len-1,0);
- if(le==0) {
- buf[len]=0;
- return;
- }
- if(le<0) {
- fprintf(stderr,"recv: error %d\n",Errno());
- exit(10);
- }
- len+=le;
- }
- buf[max-1]=0;
- }
-
- void main(int argc,char **argv) {
- struct hostent *he;
- struct servent *se;
- int sockfd,n=1,err;
- char buf[256];
- struct sockaddr_in sin;
-
- if(argc==0)
- exit(0);
- if(argc!=2) {
- fprintf(stderr,"Usage: %s host\n",argv[0]);
- exit(10);
- }
-
-
- /* miami.library versions >= 3 support T/TCP */
-
- if(MiamiBase=OpenLibrary("miami.library",3)) {
- CloseLibrary(MiamiBase);
- dottcp=1;
- }
-
-
- if(!(he=gethostbyname(argv[1]))) {
- fprintf(stderr,"Host not found\n");
- exit(10);
- }
- if(!(se=getservbyname("auth","tcp"))) {
- fprintf(stderr,"Service `auth' not found\n");
- exit(10);
- }
- if(0>(sockfd=socket(PF_INET,SOCK_STREAM,0))) {
- fprintf(stderr,"Unable to create socket\n");
- exit(10);
- }
-
- sin.sin_family=AF_INET;
- sin.sin_len=sizeof(sin);
- memcpy(&sin.sin_addr,he->h_addr,he->h_length);
- sin.sin_port=se->s_port;
-
- /* ---- start of T/TCP stuff */
- if(dottcp) {
-
- /* The following call is useful if a sendto() may be larger than
- the MSS, to ensure that packets are packed tightly. (If this seems
- strange, that's probably because it is. It has to do with some
- odd quirks in the implementation of sosend() in all BSD-derived
- TCP/IP stacks. Don't ask any questions -- just add this call
- to your program :-)).
-
- HOWEVER: only add the call if you do NOT reuse your TCP connection
- for multiple requests. If you want to transmit multiple pairs of
- "transaction"/"response" across the same TCP link (e.g. HTTP 1.1
- "persistent TCP connections"), then do NOT add the following
- call. */
-
- setsockopt(sockfd,IPPROTO_TCP,TCP_NOPUSH,(char *)&n,sizeof(n));
-
-
- /* Instead of the usual connect() followed by send(), for T/TCP you
- use a sendto() call, as you would for UDP sockets.
-
- If you have a known amount of data to send that you can send in
- a single function call, then you should use one single sendto()
- call with the MSG_EOF flag set, as in this example. This is the
- preferred way to do it, and gives best performance.
-
- If you absolutely need to loop then use a sequence like
-
- sendto(,,,0,,);
- while(!done) {
- send(,,,0);
- }
- send(,,,MSG_EOF);
-
- this means set the MSG_EOF flag in the *last* send() call only.
-
- MSG_EOF performs an implicit shutdown() for one direction of the
- link, improving performance because the shutdown() can be
- piggy-backed on data packets, i.e. no additional packets are
- needed for a shutdown() or CloseSocket() later.
-
- However *do not* use MSG_EOF if you want to re-use your
- connection for subsequent requests (e.g. "persistent TCP
- connections" in HTTP-1.1). */
-
- if(sendto(sockfd,REQUEST,strlen(REQUEST),MSG_EOF,(struct sockaddr *)&sin,
- sizeof(sin))!=strlen(REQUEST)) {
- if((err=Errno())==ENOTCONN) {
- /* T/TCP failed. Try ordinary TCP */
- dottcp=0;
- } else {
- fprintf(stderr,"sendto: error %d\n",err);
- exit(10);
- }
- }
- }
- /* ---- end of T/TCP stuff */
-
- if(!dottcp) {
- if(connect(sockfd,(struct sockaddr *)&sin,sizeof(sin))<0) {
- fprintf(stderr,"connect: error %d\n",Errno());
- exit(10);
- }
- if(send(sockfd,REQUEST,strlen(REQUEST),0)!=strlen(REQUEST)) {
- fprintf(stderr,"send: error %d\n",Errno());
- exit(10);
- }
- }
- get_response(sockfd,buf,256);
- puts(buf);
- CloseSocket(sockfd);
- }
-